﻿using System;
using System.Collections.Generic;
using TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Fundamental;

namespace TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Functions.Writers
{
    /// <summary>
    /// Writes boolean system to the simple text/plain format: x1y1z1 f11f21\nx2y2z2 f12f22.
    /// fij = {0, 1, -} - fi value on the cube with number j.
    /// </summary>
    public class BooleanSystemWriterPlain : BooleanSystemWriter
    {
        /// <summary>
        /// Result of boolean system writing.
        /// </summary>
        public string Output { get; set; }

        /// <summary>
        /// Writes BooleanSystem object to simple text/plain representation.
        /// </summary>
        public override void Write()
        {
            if (ReferenceEquals(System, null))
            {
                throw new InvalidOperationException("BooleanSystem object required (System property).");
            }

            if (!System.CheckConsistency())
            {
                throw new InvalidOperationException("Could not write system due to consistency checking failed!");
            }

            var processedCubes = new List<Cube>();
            string outputStr = String.Empty;
            foreach (var function in  System.Functions)
            {
                // processing function domain 1 and domain 0

                var funcCubeSet = new CubeSet();
                foreach (var cube in function.Domain1)
                {
                    funcCubeSet.Add(cube);
                }
                foreach (var cube in function.Domain0)
                {
                    funcCubeSet.Add(cube);
                }

                foreach (var cube in funcCubeSet)
                {
                    if (processedCubes.Contains(cube))
                    {
                        // cube has been processed, skipping...
                        continue;
                    }

                    // new system cube
                    // memorizing processed cube
                    processedCubes.Add(cube);

                    // adding system line
                    outputStr += cube + ' ';

                    // building values string
                    var values = string.Empty;
                    foreach (var t in System.Functions)
                    {
                        if (t.Domain1.Contains(cube))
                        {
                            values += '1';
                        }
                        else if (t.Domain0.Contains(cube))
                        {
                            values += '0';
                        }
                        else
                        {
                            values += '-';
                        }
                    }

                    // concatenating values
                    outputStr += values + "\r\n";
                }
            }

            // setting result
            Output = outputStr;
        }
    }
}
